﻿// <copyright file="ScaleTransform3D.cs" company="Axelerate Solutions S.A.">
// Copyright (c) Axelerate Solutions S.A.  All rights reserved.
// </copyright>

namespace Axelerate.Silverlight3D.Media.Media3D
{
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    
    /// <summary>
    /// File name: ScaleTransform3D.cs
    /// Company: Axelerate Solutions S.A.
    /// Created By: Daniel Rojas
    /// Created Date: 10/21/2008 11:50:20 h.
    /// Description: public sealed class ScaleTransform3D : AffineTransform3D
    ///   <Modifications>
    ///   </Modifications>
    /// </summary>
    public sealed class ScaleTransform3D : AffineTransform3D
    {
        #region Fields

        /// <summary>
        /// Identifies the ScaleX dependency property.
        /// </summary>
        public static readonly DependencyProperty ScaleXProperty =
                    DependencyProperty.Register(
                          "ScaleX",
                          typeof(double),
                          typeof(ScaleTransform3D),
                          new PropertyMetadata(OnScaleXPropertyChanged));

        /// <summary>
        /// Identifies the ScaleY dependency property.
        /// </summary>
        public static readonly DependencyProperty ScaleYProperty =
                    DependencyProperty.Register(
                          "ScaleY",
                          typeof(double),
                          typeof(ScaleTransform3D),
                          new PropertyMetadata(OnScaleYPropertyChanged));

        /// <summary>
        /// Identifies the ScaleZ dependency property.
        /// </summary>
        public static readonly DependencyProperty ScaleZProperty =
                    DependencyProperty.Register(
                          "ScaleZ",
                          typeof(double),
                          typeof(ScaleTransform3D),
                          new PropertyMetadata(OnScaleZPropertyChanged));

        /// <summary>
        /// Identifies the CenterX dependency property.
        /// </summary>
        public static readonly DependencyProperty CenterXProperty =
                    DependencyProperty.Register(
                          "CenterX",
                          typeof(double),
                          typeof(ScaleTransform3D),
                          new PropertyMetadata(OnCenterXPropertyChanged));

        /// <summary>
        /// Identifies the CenterY dependency property.
        /// </summary>
        public static readonly DependencyProperty CenterYProperty =
                    DependencyProperty.Register(
                          "CenterY",
                          typeof(double),
                          typeof(ScaleTransform3D),
                          new PropertyMetadata(OnCenterYPropertyChanged));

        /// <summary>
        /// Identifies the CenterZ dependency property.
        /// </summary>
        public static readonly DependencyProperty CenterZProperty =
                    DependencyProperty.Register(
                          "CenterZ",
                          typeof(double),
                          typeof(ScaleTransform3D),
                          new PropertyMetadata(OnCenterZPropertyChanged));
        #endregion

        #region Properties

        /// <summary>
        /// Gets a Matrix3D that represents the value of the translation.
        /// </summary>
        public override Matrix3D Value
        {
            get
            {
                if ((CenterX == 0) &&
                   (CenterY == 0) &&
                   (CenterZ == 0))
                {
                    //Just a scale around 0,0,0
                    return new Matrix3D(ScaleX, 0, 0, 0,
                                        0, ScaleY, 0, 0,
                                        0, 0, ScaleZ, 0,
                                        0, 0, 0, 1);
                }
                else
                {
                    //Need to scale relative to a point
                    Matrix3D result = Matrix3D.Identity;
                    result.ScaleAt(new Vector3D(ScaleX, ScaleY, ScaleZ), new Point3D(CenterX, CenterY, CenterZ));
                    return result;
                }
            }
        }

        /// <summary>
        /// Gets or sets the X-axis value of the translation's offset. This is a dependency property.
        /// </summary>
        public double ScaleX
        {
            get
            {

                return (double)this.GetValue(ScaleXProperty);
            }
            set
            {
                this.SetValue(ScaleXProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the Y-axis value of the translation's offset. This is a dependency property.
        /// </summary>
        public double ScaleY
        {
            get
            {

                return (double)this.GetValue(ScaleYProperty);
            }
            set
            {
                this.SetValue(ScaleYProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the Z-axis value of the translation's offset. This is a dependency property.
        /// </summary>
        public double ScaleZ
        {
            get
            {

                return (double)this.GetValue(ScaleZProperty);
            }
            set
            {
                this.SetValue(ScaleZProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the X-axis value of the translation's offset. This is a dependency property.
        /// </summary>
        public double CenterX
        {
            get
            {

                return (double)this.GetValue(CenterXProperty);
            }
            set
            {
                this.SetValue(CenterXProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the Y-axis value of the translation's offset. This is a dependency property.
        /// </summary>
        public double CenterY
        {
            get
            {

                return (double)this.GetValue(CenterYProperty);
            }
            set
            {
                this.SetValue(CenterYProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the Z-axis value of the translation's offset. This is a dependency property.
        /// </summary>
        public double CenterZ
        {
            get
            {

                return (double)this.GetValue(CenterZProperty);
            }
            set
            {
                this.SetValue(CenterZProperty, value);
            }
        }
        #endregion


        #region Methods
        
        /// <summary>
        /// Raise the ScaleX changed event
        /// </summary>
        /// <param name="d">DependencyObject owner of the property</param>
        /// <param name="e">DependencyPropertyChangedEventArgs with the necesary information</param>
        private static void OnScaleXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ScaleTransform3D)d).NotifyPropertyChanged("ScaleX");
        }

        /// <summary>
        /// Raise the ScaleX changed event
        /// </summary>
        /// <param name="d">DependencyObject owner of the property</param>
        /// <param name="e">DependencyPropertyChangedEventArgs with the necesary information</param>
        private static void OnScaleYPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ScaleTransform3D)d).NotifyPropertyChanged("ScaleY");
        }

        /// <summary>
        /// Raise the ScaleX changed event
        /// </summary>
        /// <param name="d">DependencyObject owner of the property</param>
        /// <param name="e">DependencyPropertyChangedEventArgs with the necesary information</param>
        private static void OnScaleZPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ScaleTransform3D)d).NotifyPropertyChanged("ScaleZ");
        }

        /// <summary>
        /// Raise the CenterX changed event
        /// </summary>
        /// <param name="d">DependencyObject owner of the property</param>
        /// <param name="e">DependencyPropertyChangedEventArgs with the necesary information</param>
        private static void OnCenterXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ScaleTransform3D)d).NotifyPropertyChanged("CenterX");
        }

        /// <summary>
        /// Raise the CenterX changed event
        /// </summary>
        /// <param name="d">DependencyObject owner of the property</param>
        /// <param name="e">DependencyPropertyChangedEventArgs with the necesary information</param>
        private static void OnCenterYPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ScaleTransform3D)d).NotifyPropertyChanged("CenterY");
        }

        /// <summary>
        /// Raise the CenterX changed event
        /// </summary>
        /// <param name="d">DependencyObject owner of the property</param>
        /// <param name="e">DependencyPropertyChangedEventArgs with the necesary information</param>
        private static void OnCenterZPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ScaleTransform3D)d).NotifyPropertyChanged("CenterZ");
        }
        #endregion

    }
}
